<!--  -->
<template>
  <div
    class="lsh-picker-box"
    :style="{ height: boxHeight }"
    @touchstart="hanDragStart"
    @touchmove.prevent="hanDragMove"
    @touchend="hanDragEnd"
    @touchcancel="hanDragEnd">
    <div
      v-for="item in dirList"
      :key="item"
      :class="`lsh-${item}-mask`"
      :style="{ height: `calc(50% - ${optionHeight / 2}px)` }"></div>
    <div
      class="lsh-content-box"
      :style="{
        transform: `translate3d(0,${transformY}px,0)`,
        transitionDuration: transitionDuration,
      }"
      @transitionend="onTransitionEnd">
      <div
        v-for="(item, index) in columns"
        :style="{ height: `${optionHeight}px` }"
        :class="[
          'lsh-content-item',
          {
            disabled: item.disabled,
          },
        ]"
        @click="clickOption(item, index)">
        {{ item.label }}
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, withDefaults, computed } from "vue";
import { PickerOption, PickerPanelProps } from "./type";
import { isUndefined } from "@/utils/is";
import { useMomentumCalculation } from "./hooks/useMomentumCalculation";
const props = withDefaults(defineProps<PickerPanelProps>(), {
  visibleOptionNum: 6,
  optionHeight: 44,
  modelValue: () => [],
  columns: () => [],
  swipeDuration: 1000,
  clickDuration: 200,
});
const emit = defineEmits(["update:modelValue"]);
const dirList = ["top", "bottom"];
const selectedIndexList = ref<number[]>([]);
const momentumCalc = useMomentumCalculation({
  deceleration: 0.001,
  minVelocity: 0.05,
});
// 控制是否启用过渡动画
const transitionDuration = ref("0ms");
const getStartY = () => {
  return ((props.visibleOptionNum - 1) * props.optionHeight) / 2;
};
const getEndY = () => {
  const listLength = props.columns.length;
  return -(listLength - 1) * props.optionHeight + getStartY();
};
const transformY = ref(getStartY());
const boxHeight = computed(() => {
  return props.visibleOptionNum * props.optionHeight + "px";
});
let lastY: number | undefined;
let draging = false;
const openTransition = (type: "swipe" | "click") => {
  transitionDuration.value =
    (type === "swipe" ? props.swipeDuration : props.clickDuration) + "ms";
};
const closeTransition = () => {
  transitionDuration.value = "0ms";
};
const hanDragStart = (e: TouchEvent) => {
  if (draging) return;
  draging = true;
  // 禁用过渡动画，使拖拽更流畅
  closeTransition();
  const touch = e.touches[0];
  lastY = touch.clientY;
  // 开始跟踪位置变化
  momentumCalc.startTracking(touch.clientY);
};
const hanDragMove = (e: TouchEvent) => {
  if (!draging) return;
  if (isUndefined(lastY)) return;
  const touch = e.touches[0];
  // 更新位置信息并计算速度
  momentumCalc.updatePosition(touch.clientY);
  const moveY = touch.clientY - lastY;
  //最小和最大分别增加一个,实现到底和顶都可以拖动
  const maxY = getStartY() + props.optionHeight;
  const minY = getEndY() - props.optionHeight;
  transformY.value = Math.max(Math.min(maxY, transformY.value + moveY), minY);
  lastY = touch.clientY;
};
// 计算选中项
const calcSelected = () => {
  const y = -transformY.value + getStartY();
  const selectedIndex = Math.max(
    Math.min(Math.round(y / props.optionHeight), props.columns.length - 1),
    0
  );
  transformY.value = -selectedIndex * props.optionHeight + getStartY();
};
const hanDragEnd = () => {
  draging = false;
  lastY = undefined;
  // 计算惯性滚动
  const momentumResult = momentumCalc.calculateMomentum(
    transformY.value,
    getEndY(), // 最小位置
    getStartY() // 最大位置
  );

  // 如果应该应用惯性，应用惯性滚动目标位置
  if (momentumResult.shouldApply)
    transformY.value = momentumResult.targetPosition;
  // 如果应该应用惯性，启用过渡动画
  // 即使没有惯性，也启用过渡动画来平滑回到正确位置
  openTransition("swipe");
  calcSelected();
  // 重置惯性计算状态
  momentumCalc.reset();
};
const onTransitionEnd = () => {
  const y = -transformY.value + getStartY();
  const index = y / props.optionHeight;
  const selectOpitons = props.columns[index];
  if (selectOpitons?.disabled) {
  }else {
    selectedIndexList.value[0] = index;
  }
  closeTransition();
  onChange();
};
const clickOption = (item: PickerOption, index: number) => {
  if (item?.disabled) return;
  openTransition("click");
  selectedIndexList.value[0] = index;
  transformY.value = -index * props.optionHeight + getStartY();
};
const getSelectedOptions = () =>{

}
const onChange = () => {
  const selectedValueList = selectedIndexList.value.map((itemIndex,index) => {
    return props.columns[itemIndex].value;
  });
  console.log("selectedValueList",selectedValueList)
  emit("update:modelValue", selectedValueList);
};
</script>
<style scoped lang="less">
.lsh-picker-box {
  width: 100%;
  position: relative;
  overflow: hidden;
  .lsh-top-mask,
  .lsh-bottom-mask {
    position: absolute;
    left: 0;
    width: 100%;
    background:
      linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.9),
        rgba(255, 255, 255, 0.4)
      ),
      linear-gradient(0deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.4));
    z-index: 1;
    pointer-events: none;
  }
  .lsh-top-mask {
    top: 0;
    border-bottom: 1px solid #ddd;
  }
  .lsh-bottom-mask {
    bottom: 0;
    border-top: 1px solid #ddd;
  }
  .lsh-content-box {
    height: 100%;
    width: 100%;
    transform: translate3d(0, 110px, 0);
    // 默认禁用过渡效果（开启时用于惯性滚动）
    transition: transform 0s cubic-bezier(0.23, 1, 0.68, 1);
    .lsh-content-item {
      width: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      user-select: none;
      cursor: grab;
      &.disabled {
        cursor: not-allowed;
        opacity: 0.5;
      }
    }
  }
}
</style>
